package org.ciallo.simplemusicplayer.viewmodel;

import android.app.Application;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations;
import org.ciallo.simplemusicplayer.data.model.AlbumInfo;
import org.ciallo.simplemusicplayer.data.model.ArtistInfo;
import org.ciallo.simplemusicplayer.data.model.FolderInfo;
import org.ciallo.simplemusicplayer.data.model.Song;
import org.ciallo.simplemusicplayer.data.repository.SongRepository;
import timber.log.Timber;

import java.util.List;
import java.util.Objects;

/**
 * @author Jukomu
 * @Description: "本地音乐"模块中与歌曲列表相关的ViewModel
 * 负责提供歌曲数据、处理媒体库扫描请求，并向上层UI暴露扫描状态
 * @Package: org.ciallo.simplemusicplayer.viewmodel
 * @Project: SimpleMusicPlayer
 * @name: LocalMusicViewModel
 * @Date: 2025/5/31-00:24
 * @Filename: LocalMusicViewModel
 */
public class LocalMusicViewModel extends AndroidViewModel { // 继承 AndroidViewModel 以便访问 Application Context

    private final SongRepository songRepository;


    /**
     * LiveData，指示当前是否正在进行媒体库扫描。
     * UI 可以观察这个 LiveData 来显示加载指示器 (如 SwipeRefreshLayout 的刷新动画)。
     */
    public final LiveData<Boolean> isScanning;


    // 用于保存来自 SharedViewModel 的当前搜索查询词
    private final MutableLiveData<String> currentLocalSearchQuery = new MutableLiveData<>();

    /**
     * LiveData，根据 currentLocalSearchQuery 的值，动态提供所有歌曲或过滤后的歌曲列表。
     * UI (如 SongListFragment) 将观察这个 LiveData。
     */
    public final LiveData<List<Song>> songsToDisplay;
    public final LiveData<List<ArtistInfo>> artistsToDisplay;
    public final LiveData<List<AlbumInfo>> albumsToDisplay;
    public final LiveData<List<FolderInfo>> foldersToDisplay;


    /**
     * 构造函数。
     *
     * @param application Application 实例。
     */
    public LocalMusicViewModel(@NonNull Application application) {
        super(application);
        songRepository = new SongRepository(application);
        isScanning = songRepository.isScanning;
        currentLocalSearchQuery.setValue(""); // 初始为空

        songsToDisplay = Transformations.switchMap(currentLocalSearchQuery, query -> {
            Timber.d("LVM songsToDisplay switchMap query: '%s'", query);
            return songRepository.getSongsFilteredOrAllSortedByPinyin(query); // 使用之前为单曲搜索创建的方法
        });

        artistsToDisplay = Transformations.switchMap(currentLocalSearchQuery, query -> {
            Timber.d("LVM artistsToDisplay switchMap query: '%s'", query);
            return songRepository.getArtistsInfoFilteredOrAllSortedByPinyin(query);
        });

        albumsToDisplay = Transformations.switchMap(currentLocalSearchQuery, query -> {
            Timber.d("LVM albumsToDisplay switchMap query: '%s'", query);
            return songRepository.getAlbumsInfoFilteredOrAllSortedByPinyin(query);
        });

        foldersToDisplay = Transformations.switchMap(currentLocalSearchQuery, query -> {
            Timber.d("LVM foldersToDisplay switchMap query: '%s'", query);
            return songRepository.getMusicFoldersFilteredOrAllSortedByName(query);
        });
    }

    /**
     * 触发一次媒体库扫描。
     * 此方法会调用 SongRepository 中的扫描逻辑。
     * UI层（例如下拉刷新时）可以调用此方法。
     */
    public void startMediaStoreScan() {
        Timber.d("LocalMusicViewModel: MediaStore scan triggered.");
        songRepository.refreshSongsFromMediaStore();
        // isScanning LiveData 会由 SongRepository 内部更新
        // 如果扫描出错，SongRepository 内部目前只记录日志，
        // 如果需要通知UI，可以在Repository中也暴露一个error LiveData，或者在这里处理Repository可能抛出的异常
    }


    /**
     * (可选) 获取扫描状态的 LiveData。
     *
     * @return LiveData<Boolean> 指示是否正在扫描。
     */
    public LiveData<Boolean> getScanningStatus() {
        return isScanning;
    }

    /**
     * 根据歌手名获取该歌手的所有歌曲。
     *
     * @param artistName 歌手名。
     * @return LiveData 包装的歌曲列表。
     */
    public LiveData<List<Song>> getSongsByArtist(String artistName) {
        return songRepository.getSongsByArtistName(artistName);
    }

    /**
     * 根据专辑ID获取该专辑的所有歌曲。
     *
     * @param albumId 专辑ID。
     * @return LiveData 包装的歌曲列表。
     */
    public LiveData<List<Song>> getSongsByAlbumId(long albumId) {
        return songRepository.getSongsByAlbumId(albumId);
    }

    /**
     * 根据文件夹路径获取该文件夹下的所有歌曲。
     *
     * @param folderPath 文件夹路径。
     * @return LiveData 包装的歌曲列表。
     */
    public LiveData<List<Song>> getSongsInFolder(String folderPath) {
        return songRepository.getSongsInFolderPath(folderPath);
    }

    /**
     * 供外部设置搜索查询词的方法。
     * 通常由观察 SharedViewModel.currentSearchQuery 的UI组件调用。
     *
     * @param query 新的搜索查询。
     */
    public void updateSearchQuery(@Nullable String query) {
        String newQuery = (query != null) ? query.trim() : "";
        if (!Objects.equals(newQuery, currentLocalSearchQuery.getValue())) {
            currentLocalSearchQuery.setValue(newQuery);
        }
    }
}
